/**
 * 菜单转换工具
 * 将后端返回的菜单数据转换为前端路由格式
 */

import type { RouteRecordStringComponent } from '@vben/types';

import type { Menu, MenuType } from '#/api';

// 用于跟踪已使用的路由名称，避免重复
const usedRouteNames = new Set<string>();

/**
 * 将后端菜单数据转换为前端路由格式
 * @param menus 后端菜单列表
 * @returns 前端路由列表
 */
export function transformMenusToRoutes(
  menus: Menu[],
): RouteRecordStringComponent[] {
  if (!menus || menus.length === 0) {
    return [];
  }

  // 每次转换前清空已使用的路由名称集合
  usedRouteNames.clear();

  return menus
    .map((menu) => transformMenuToRoute(menu))
    .filter((route): route is RouteRecordStringComponent => route !== null);
}

/**
 * 将单个菜单转换为路由
 * @param menu 后端菜单对象
 * @returns 前端路由对象
 */
function transformMenuToRoute(menu: Menu): RouteRecordStringComponent | null {
  // 菜单类型：1=目录，2=菜单，3=按钮
  // 或字符串：DIRECTORY=目录，MENU=菜单，BUTTON=按钮
  // 按钮类型不需要转换为路由
  let menuType = normalizeMenuType(menu.menuType || menu.type);
  if (menuType === 3 || menuType === 'BUTTON') {
    console.log('⏭️ 跳过按钮类型菜单:', menu.menuName);
    return null;
  }

  // 如果菜单不可见，跳过
  if (menu.visible === 0) {
    return null;
  }

  // 🔧 修正：如果菜单有子菜单，自动将其视为目录类型
  // 这样可以避免父菜单和子菜单使用相同组件的问题
  const hasChildren = menu.children && menu.children.length > 0;
  if (hasChildren && menuType === 2) {
    console.warn(`⚠️ 菜单 "${menu.menuName}" 有子菜单但类型为菜单(2)，自动转换为目录类型(1)`);
    menuType = 1;
  }

  // 生成唯一的路由名称
  const routeName = generateUniqueRouteName(menu);
  const componentPath = getComponentPath(menu, menuType);

  // 🔍 调试：打印限流相关菜单的详细信息
  if (menu.menuName?.includes('限流')) {
    console.log('🔍 限流菜单转换:', {
      menuName: menu.menuName,
      path: menu.path,
      component: menu.component,
      routeName,
      componentPath,
      menuType,
      hasChildren,
    });
  }

  // 构建路由对象
  const route: RouteRecordStringComponent = {
    name: routeName,
    path: menu.path || '/',
    component: componentPath,
    meta: {
      title: menu.menuName,
      icon: menu.icon || undefined,
      order: menu.sort || 0,
      // 如果有权限标识，添加到 meta 中
      ...(menu.permission ? { permission: menu.permission } : {}),
      // 如果有外链地址，添加到 meta 中
      ...(menu.link ? { link: menu.link } : {}),
      // 目录类型不需要 hideChildrenInMenu
      ...(menuType === 1 ? {} : {}),
    },
  };

  // 递归处理子菜单
  if (hasChildren) {
    const childRoutes = transformMenusToRoutes(menu.children!);
    if (childRoutes.length > 0) {
      route.children = childRoutes;
    }
  }

  return route;
}

/**
 * 生成路由名称
 * @param menu 菜单对象
 * @returns 路由名称
 */
function generateRouteName(menu: Menu): string {
  // 如果菜单有自定义的路由名称，使用自定义名称
  // 否则根据路径生成名称
  const path = menu.path || '';

  // 移除开头的斜杠，将路径转换为驼峰命名
  // 例如：/system/user -> SystemUser
  // 例如：/system/rate-limit -> SystemRateLimit
  return path
    .split('/')
    .filter((segment) => segment)
    .map((segment) => {
      // 将连字符分隔的单词转换为驼峰命名
      // 例如：rate-limit -> RateLimit
      return segment
        .split('-')
        .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
        .join('');
    })
    .join('');
}

/**
 * 生成唯一的路由名称
 * @param menu 菜单对象
 * @returns 唯一的路由名称
 */
function generateUniqueRouteName(menu: Menu): string {
  // 优先使用菜单ID作为唯一标识
  if (menu.id) {
    const baseName = generateRouteName(menu);
    const uniqueName = `${baseName}_${menu.id}`;
    return uniqueName;
  }

  // 如果没有ID，使用路径生成基础名称
  let baseName = generateRouteName(menu);

  // 如果名称已被使用，添加后缀确保唯一性
  if (usedRouteNames.has(baseName)) {
    let counter = 1;
    let uniqueName = `${baseName}${counter}`;
    while (usedRouteNames.has(uniqueName)) {
      counter++;
      uniqueName = `${baseName}${counter}`;
    }
    baseName = uniqueName;
    console.warn(`⚠️ 检测到重复的路由名称，已自动重命名为: ${baseName}`);
  }

  // 记录已使用的名称
  usedRouteNames.add(baseName);

  return baseName;
}

/**
 * 标准化菜单类型
 * @param menuType 菜单类型（可能是数字或字符串）
 * @returns 标准化后的菜单类型
 */
function normalizeMenuType(menuType: any): number | string {
  if (typeof menuType === 'string') {
    // 字符串类型，直接返回
    return menuType;
  }
  // 数字类型，直接返回
  return Number(menuType);
}

/**
 * 获取组件路径
 * @param menu 菜单对象
 * @param menuType 菜单类型
 * @returns 组件路径
 */
function getComponentPath(menu: Menu, menuType: MenuType | number | string): string {
  // 如果是目录类型（menuType = 1 或 'DIRECTORY'），返回特殊标记
  // 这个标记会在路由生成时被替换为 RouterView 组件
  if (menuType === 1 || menuType === 'DIRECTORY') {
    return '__ROUTER_VIEW__';
  }

  // 如果是菜单类型（menuType = 2），使用 component 字段
  if (menu.component) {
    // 后端返回的 component 格式：
    // #/views/system/user/index.vue
    // /views/system/user/index.vue
    // views/system/user/index.vue
    // /views/system/user/index (没有.vue后缀)
    let componentPath = menu.component;

    // 移除开头的 #/ 或 /
    componentPath = componentPath.replace(/^#\//, '').replace(/^\//, '');

    // 如果路径没有 .vue 后缀，自动添加
    if (!componentPath.endsWith('.vue')) {
      componentPath = `${componentPath}.vue`;
    }

    // 确保路径以 ../ 开头（相对于 router 目录）
    if (!componentPath.startsWith('../')) {
      componentPath = `../${componentPath}`;
    }

    return componentPath;
  }

  // 默认返回空字符串
  return '';
}

/**
 * 打印菜单转换日志（用于调试）
 * @param menus 原始菜单列表
 * @param routes 转换后的路由列表
 */
export function debugMenuTransform(
  menus: Menu[],
  routes: RouteRecordStringComponent[],
) {
  console.group('🔄 菜单转换调试信息');
  console.log('原始菜单数据:', menus);
  console.log('转换后的路由:', routes);
  console.log('菜单数量:', menus.length);
  console.log('路由数量:', routes.length);
  console.groupEnd();
}

/**
 * 验证菜单数据
 * @param menus 菜单列表
 * @returns 验证结果
 */
export function validateMenus(menus: Menu[]): {
  valid: boolean;
  errors: string[];
} {
  const errors: string[] = [];

  function validateMenu(menu: Menu, path: string = '') {
    const currentPath = path ? `${path} > ${menu.menuName}` : menu.menuName;

    // 检查必填字段
    if (!menu.menuName) {
      errors.push(`${currentPath}: 缺少菜单名称`);
    }

    if (!menu.menuType && !menu.type) {
      errors.push(`${currentPath}: 缺少菜单类型`);
    }

    // 如果是菜单类型，检查 path 和 component
    const menuType = normalizeMenuType(menu.menuType || menu.type);
    if (menuType === 2 || menuType === 'MENU') {
      if (!menu.path) {
        errors.push(`${currentPath}: 菜单类型必须有路由地址`);
      }
      if (!menu.component) {
        errors.push(`${currentPath}: 菜单类型必须有组件路径`);
      }
    }

    // 递归验证子菜单
    if (menu.children && menu.children.length > 0) {
      for (const child of menu.children) {
        validateMenu(child, currentPath);
      }
    }
  }

  for (const menu of menus) {
    validateMenu(menu);
  }

  return {
    valid: errors.length === 0,
    errors,
  };
}

/**
 * 合并静态路由和动态路由
 * @param staticRoutes 静态路由（前端定义）
 * @param dynamicRoutes 动态路由（后端返回）
 * @returns 合并后的路由列表
 */
export function mergeRoutes(
  staticRoutes: RouteRecordStringComponent[],
  dynamicRoutes: RouteRecordStringComponent[],
): RouteRecordStringComponent[] {
  // 简单合并：动态路由优先
  // 如果需要更复杂的合并逻辑（如去重、覆盖等），可以在这里实现
  return [...dynamicRoutes, ...staticRoutes];
}

